const std = @import("std");

pub fn build(b: *std.Build) void {
    const optimize = b.standardOptimizeOption(.{});
    const target = b.resolveTargetQuery(.{
        .cpu_arch = .riscv32,
        .os_tag = .freestanding,
        .abi = .none,
    });

    // build os.elf
    const os = b.addExecutable(.{
        .name = "os",
        .root_module = b.createModule(.{
            .root_source_file = b.path("kernel.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    os.setLinkerScript(b.path("linker.ld"));

    const install_os = b.addInstallArtifact(os, .{
        .dest_dir = .{ .override = .{ .custom = "" } },
    });
    b.getInstallStep().dependOn(&install_os.step);

    // other steps
    const qemu_args = .{
        "-smp",       "1",
        "-machine",   "virt",
        "-bios",      "none",
        "-nographic",
    };

    // run qemu
    var run_tls = b.step("run", "Run os in QEMU");
    var run = b.addSystemCommand(&.{"qemu-system-riscv32"});
    run.addArgs(&(qemu_args ++ .{"-kernel"}));
    run.addArtifactArg(os);
    run_tls.dependOn(&run.step);

    // run qemu with gdb server
    var qemu_tls = b.step("qemu", "Run os in QEMU with gdb server");
    var qemu = b.addSystemCommand(&.{"qemu-system-riscv32"});
    qemu.addArgs(&(qemu_args ++ .{ "-s", "-S", "-kernel" }));
    qemu.addArtifactArg(os);
    qemu_tls.dependOn(&qemu.step);

    // debug with gdb
    var gdb_tls = b.step("gdb", "Debug with gdb");
    var gdb = b.addSystemCommand(&.{ "gdb-multiarch", "-q", "-x", "gdbinit" });
    gdb.addArtifactArg(os);
    gdb_tls.dependOn(&gdb.step);

    // display code information
    var objdump_tls = b.step("code", "Display code information");
    var objdump = b.addSystemCommand(&.{ "riscv64-unknown-elf-objdump", "-SD" });
    objdump.addArtifactArg(os);
    objdump_tls.dependOn(&objdump.step);
}
